package com.cesc.demo.interfaces.api;

import com.cesc.demo.application.service.ProductAppService;
import com.cesc.demo.domain.product.PageResult;
import com.cesc.demo.domain.product.entity.Product;

import com.cesc.demo.interfaces.assembler.ResponseResultFactory;
import com.cesc.demo.interfaces.dto.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.List;

@RestController
@Api(tags = "商品接口")
@RequestMapping("/product")
public class ProductController {
    @Autowired
    private ProductAppService productAppService;



    @ApiOperation(value="保存商品信息到mysql", notes="")
    @PostMapping("/db/save")
    public Mono<ResponseEntity<ResponseResult<Product>>> saveProductToDb(@RequestBody Product product){
        Mono<Product> productMono=this.productAppService.saveByRespository(product);
        ResponseResultFactory<Product> responseResultFactory=new ResponseResultFactory<>();

        return productMono.map(returnProduct->{
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(returnProduct,200,"Ok");
            return responseResutl;
        }).onErrorResume(e->{
            System.out.println("api error"); //记录日志
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(null,500,"Error");
            return Mono.just(responseResutl);
        });
    }



    @ApiOperation(value="根据ID删除商品", notes="")
    @DeleteMapping("/db/delete")
    public Mono<ResponseEntity<ResponseResult<Boolean>>> deleteById(Long id ){
        Mono<Void> productMono=this.productAppService.deletByIdByRespository(id);
        ResponseResultFactory<Boolean> responseResultFactory=new ResponseResultFactory<>();
        ResponseEntity<ResponseResult<Boolean>>  defaultResponse=responseResultFactory.build(true,200,"操作成功");

        return productMono.map(result-> defaultResponse).onErrorResume(e->{
            System.out.println("api error"); //记录日志
            System.out.println(e.toString());
            ResponseEntity<ResponseResult<Boolean>>  responseResutl=responseResultFactory.build(false,500,e.getMessage());
            return Mono.just(responseResutl);
        }).switchIfEmpty(Mono.just(defaultResponse));
    }



    @ApiOperation(value="保存商品信息到mysql,出错回滚", notes="")
    @PostMapping("/db/rollbacksave")
    public Mono<ResponseEntity<ResponseResult<Product>>> saveProductToDbAndRollBack(@RequestBody Product product){
        Mono<Product> productMono=this.productAppService.saveByRespositoryWithRollBack(product);
        ResponseResultFactory<Product> responseResultFactory=new ResponseResultFactory<>();
        return productMono.map(returnProduct->{
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(returnProduct,200,"Ok");
            return responseResutl;
        }).onErrorResume(e->{
            System.out.println("api error"); //记录日志
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(null,500,"Error");
            return Mono.just(responseResutl);
        });
    }

    @ApiOperation(value="根据ID查找商品", notes="")
    @GetMapping("/db/findbyid")
    public Mono<ResponseEntity<ResponseResult<Product>>> findById(Long id){

        Mono<Product> productMono=this.productAppService.findByRespository(id);
        ResponseResultFactory<Product> responseResultFactory=new ResponseResultFactory<>();
        ResponseEntity<ResponseResult<Product>>  defalulResponse=responseResultFactory.build(null,500,"Error");

        return productMono.map(returnProduct->{
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(returnProduct,200,"Ok");
            return responseResutl;
        }).onErrorResume(e->{
            System.out.println("api error"); //记录日志
            return Mono.just(defalulResponse);
        }).switchIfEmpty(Mono.just(defalulResponse));
    }



    @ApiOperation(value="通过底层API保存商品信息到mysql", notes="")
    @PostMapping("/db/savebyapi")
    public Mono<ResponseEntity<ResponseResult<Product>>> saveProductToDbByApi(@RequestBody Product product){

        Mono<Product> productMono=this.productAppService.saveByAccessApi(product);
        ResponseResultFactory<Product> responseResultFactory=new ResponseResultFactory<>();

        return productMono.map(returnProduct->{
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(returnProduct,200,"Ok");
            return responseResutl;
        }).onErrorResume(e->{
            System.out.println("api error"); //记录日志
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(null,500,"Error");
            return Mono.just(responseResutl);
        });
    }


    @ApiOperation(value="通过底层API更新商品信息到mysql", notes="")
    @PostMapping("/db/updatebyapi")
    public Mono<ResponseEntity<ResponseResult<Product>>> updateProductToDbByApi(@RequestBody Product product){

        Mono<Product> productMono=this.productAppService.updateByAccessApi(product);
        ResponseResultFactory<Product> responseResultFactory=new ResponseResultFactory<>();

        return productMono.map(returnProduct->{
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(returnProduct,200,"Ok");
            return responseResutl;
        }).onErrorResume(e->{
            System.out.println("api error"); //记录日志
            ResponseEntity<ResponseResult<Product>>  responseResutl=responseResultFactory.build(null,500,"Error");
            return Mono.just(responseResutl);
        });
    }


    @ApiOperation(value="通过底层API删除保存商品信息", notes="")
    @DeleteMapping("/db/deletebyapi")
    public Mono<ResponseEntity<ResponseResult<Integer>>> deleteProductToDbByApi(@RequestBody Product product){

        Mono<Integer> productMono=this.productAppService.deleteByAccessApi(product);
        ResponseResultFactory<Integer> responseResultFactory=new ResponseResultFactory<>();

        return productMono.map(rowAffect->{
            ResponseEntity<ResponseResult<Integer>>  responseResutl=responseResultFactory.build(rowAffect,200,"Ok");
            return responseResutl;
        }).onErrorResume(e->{
            System.out.println("api error"); //记录日志
           ResponseEntity<ResponseResult<Integer>>  responseResutl=responseResultFactory.build(0,500,"Error");
            return Mono.just(responseResutl);
        });
    }


    @ApiOperation(value="通过底层API分页查询数据", notes="")
    @GetMapping("/db/pagebyapi")
    public Mono<ResponseEntity<ResponseResult<PageResult<Product>>>> findProductFromDbByApi( Product product,int pageSize,int page){
        Mono<PageResult<Product>> productMono=this.productAppService.findByAccessApi(product,pageSize,page);

        ResponseResultFactory<PageResult<Product>> responseResultFactory=new ResponseResultFactory<>();
        ResponseEntity<ResponseResult<PageResult<Product>>>  defaultResponse=responseResultFactory.build(null,500,"Error");

        return productMono.map(pageResult->{
            ResponseEntity<ResponseResult<PageResult<Product>>>  responseResutl=responseResultFactory.build(pageResult,200,"Ok");
            return responseResutl;
        }).onErrorResume(e-> Mono.just(defaultResponse)).switchIfEmpty(Mono.just(defaultResponse)); //为空时默认返回结果
    }

    @ApiOperation(value="根据商品名查询商品", notes="")
    @ApiImplicitParam(name = "productName", value = "商品名", defaultValue="", required = false)
    @GetMapping("/db/findbyname")
    public Mono<ResponseEntity<ResponseResult<List<Product>>>> findProductByName(String productName){
        Mono<List<Product>> productMono=this.productAppService.findProductByProductNameEquals(productName);

        ResponseResultFactory<List<Product>> responseResultFactory=new ResponseResultFactory<>();
        ResponseEntity<ResponseResult<List<Product>>>  defaultResponse=responseResultFactory.build(null,500,"Error");

        return productMono.map(result->{
            ResponseEntity<ResponseResult<List<Product>>>  responseResutl=responseResultFactory.build(result,200,"Ok");
            return responseResutl;
        }).onErrorResume(e-> Mono.just(defaultResponse)).switchIfEmpty(Mono.just(defaultResponse)); //为空时默认返回结果
    }
}
